package lexical;

import java.util.ArrayList;

public class Analyse {
    public ArrayList<Word> words = new ArrayList<>();
    public ArrayList<String> lines;

    public Analyse(ArrayList<String> lines) {
        this.lines = lines;
        startMachine();
    }

    public ArrayList<Word> getWords() {
        return words;
    }

    public void startMachine() {
        boolean annotationFlag = false;
        int lineNum = 0;
        for (String line : lines) {
            lineNum++;
            for (int i = 0; i < line.length(); i++) {
                if (annotationFlag) {
                    if (line.charAt(i) == '*' && line.charAt(i+1) == '/') {
                        annotationFlag = false;
                        i++;
                    }
                } else if (line.charAt(i) == '/') {
                    if (line.charAt(i + 1) == '/') {
                        break;
                    } else if (line.charAt(i + 1) == '*') {
                        annotationFlag = true;
                        i++;
                    } else {
                        words.add(new Word("/", Key.DIV, lineNum));
                    }
                } else if ((line.charAt(i) >= 'a' && line.charAt(i) <= 'z') || (line.charAt(i) >= 'A' && line.charAt(i) <= 'Z') || line.charAt(i) == '_') {
                    StringBuilder word = new StringBuilder();
                    while ((line.charAt(i) >= 'a' && line.charAt(i) <= 'z') || (line.charAt(i) >= 'A' && line.charAt(i) <= 'Z') || line.charAt(i) == '_' || (line.charAt(i) >= '0' && line.charAt(i) <= '9')) {
                        word.append(line.charAt(i++));
                    }
                    i--;
                    words.add(new Word(word.toString(), Key.isReservedWord(word.toString()), lineNum));
                } else if (line.charAt(i) == '"') {
                    StringBuilder word = new StringBuilder();
                    word.append(line.charAt(i++));
                    while (line.charAt(i) != '"') {
                        word.append(line.charAt(i++));
                    }
                    word.append(line.charAt(i));
                    words.add(new Word(word.toString(), Key.STRCON, lineNum));
                } else if (line.charAt(i) >= '0' && line.charAt(i) <= '9') {
                    StringBuilder word = new StringBuilder();
                    while (line.charAt(i) >= '0' && line.charAt(i) <= '9') {
                        word.append(line.charAt(i++));
                    }
                    i--;
                    words.add(new Word(word.toString(), Key.INTCON, lineNum));
                } else if (line.charAt(i) == '&' && line.charAt(i + 1) == '&') {
                    words.add(new Word("&&", Key.AND, lineNum));
                    i++;
                } else if (line.charAt(i) == '|' && line.charAt(i + 1) == '|') {
                    words.add(new Word("||", Key.OR, lineNum));
                } else if (line.charAt(i) == '+') {
                    words.add(new Word("+", Key.PLUS, lineNum));
                } else if (line.charAt(i) == '-') {
                    words.add(new Word("-", Key.MINU, lineNum));
                } else if (line.charAt(i) == '*') {
                    words.add(new Word("*", Key.MULT, lineNum));
                } else if (line.charAt(i) == '%') {
                    words.add(new Word("%", Key.MOD, lineNum));
                } else if (line.charAt(i) == '!') {
                    if (line.charAt(i + 1) == '=') {
                        words.add(new Word("!=", Key.NEQ, lineNum));
                        i++;
                    } else {
                        words.add(new Word("!", Key.NOT, lineNum));
                    }
                } else if (line.charAt(i) == '<') {
                    if (line.charAt(i + 1) == '=') {
                        words.add(new Word("<=", Key.LEQ, lineNum));
                        i++;
                    } else {
                        words.add(new Word("<", Key.LSS, lineNum));
                    }
                } else if (line.charAt(i) == '>') {
                    if (line.charAt(i + 1) == '=') {
                        words.add(new Word(">=", Key.GEQ, lineNum));
                        i++;
                    } else {
                        words.add(new Word(">", Key.GRE, lineNum));
                    }
                } else if (line.charAt(i) == '=') {
                    if (line.charAt(i + 1) == '=') {
                        words.add(new Word("==", Key.EQL, lineNum));
                        i++;
                    } else {
                        words.add(new Word("=", Key.ASSIGN, lineNum));
                    }
                } else if (line.charAt(i) == ';') {
                    words.add(new Word(";", Key.SEMICN, lineNum));
                } else if (line.charAt(i) == ',') {
                    words.add(new Word(",", Key.COMMA, lineNum));
                } else if (line.charAt(i) == '(') {
                    words.add(new Word("(", Key.LPARENT, lineNum));
                } else if (line.charAt(i) == ')') {
                    words.add(new Word(")", Key.RPARENT, lineNum));
                } else if (line.charAt(i) == '[') {
                    words.add(new Word("[", Key.LBRACK, lineNum));
                } else if (line.charAt(i) == ']') {
                    words.add(new Word("]", Key.RBRACK, lineNum));
                } else if (line.charAt(i) == '{') {
                    words.add(new Word("{", Key.LBRACE, lineNum));
                } else if (line.charAt(i) == '}') {
                    words.add(new Word("}", Key.RBRACE, lineNum));
                }
            }
        }
    }

    public String toString() {
        StringBuilder s = new StringBuilder();
        for (Word word : words) {
            s.append(word.toString()).append("\n");
        }
        String str = s.toString();
        return str.substring(0, str.length() - 1);
    }
}
